// 12.2.4 模板参数包
// 模板参数包（Template Parameter Packs）是C++11引入的一项重要特性，它允许模板接受任意数量的参数。这大大增强了C++模板的灵活性和表达能力，为可变参数模板（Variadic Templates）提供了基础。

// 基本语法
// 模板参数包使用省略号（...）语法声明：
// 类型参数包
template <typename... Types>
class Tuple
{
    // ...
};

// 非类型参数包
template <int... Values>
class IntegerSequence
{
    // ...
};

// 混合参数包
template <typename T, typename... Rest>
class VariadicContainer
{
    // ...
};

// 参数包的种类
// C++支持三种类型的模板参数包：
// 1.类型参数包：表示任意数量的类型
template <typename... Types>

// 2.非类型参数包：表示任意数量的非类型参数
template <int... Values>

// 3.模板模板参数包：表示任意数量的模板模板参数
template <template <typename> class... Templates>

// 参数包的展开
// 参数包必须使用省略号（...）进行展开：
template <typename... Types>
class Tuple
{
    // ...
};

template <typename... Types>
void printTypes()
{
    // 展开参数包
    (std::cout << typeid(Types).name() << ", " ...);
}

// 参数包展开的上下文
// 参数包可以在多种上下文中展开：
// 1.函数参数：
template <typename... Args>
void forward(Args &&...args)
{
    someFunction(std::forward<Args>(args)...);
}

// 2.初始化列表：
template <typename... Types>
auto makeArray(Types &&...args)
{
    return std::array<std::common_type_t<Types...>, sizeof...(Types)>{
        std::forward<Types>(args)...};
}

// 3.基类列表：
template <typename... Mixins>
class Combined : public Mixins...
{
    // ...
};

// 4.模板实例化：
template <typename... Types>
using TupleOfVectors = std::tuple<std::vector<Types>...>;

// 递归展开（C++11/14）
// 在C++17之前，参数包通常通过递归模板实例化展开：
// 基本情况
template <typename T>
void print(T value)
{
    std::cout << value << std::endl;
}

// 递归情况
template <typename First, typename... Rest>
void print(First first, Rest... rest)
{
    std::cout << first << ", ";
    print(rest...); // 递归调用
}

// 参数包的应用
// 参数包在多种场景中非常有用：
// 1.完美转发：
template <typename... Args>
auto createObject(Args &&...args)
{
    return new Object(std::forward<Args>(args)...);
}

// 2.元组实现：
template <typename... Types>
class Tuple
{
    // ...
};

// 3.可变参数函数：
template <typename... Args>
void log(const char *format, Args... args)
{
    printf(format, args...);
}
